#ifndef SPL_CONTROL
#define SPL_CONTROL

struct ControlPaintEvent
{
  Gdip::Graphics& graphics;
  const Gdip::Rect& bounds;
  const Geom::Rect& update;

  ControlPaintEvent(
    Gdip::Graphics& iGraphics,
    Gdip::Rect& iBounds,
    Geom::Rect& iUpdate
    ) :
    bounds(iBounds),
    update(iUpdate),
    graphics(iGraphics)
  {
  }
};

struct ControlTheme
{
  COLORREF frameBg;
  COLORREF frameSurface;
  COLORREF frameLight;
  COLORREF frameDark;
  COLORREF frameHover;
  COLORREF borderLight;
  COLORREF borderDark;
  COLORREF containerBorder;
  COLORREF containerBg;
  COLORREF textLight;
  COLORREF textDark;
  COLORREF textDisabled;
};

enum ThemeStyle
{
  ThemeDefault,
  ThemeOrange,
  ThemeBlue,
  ThemeFirst = ThemeDefault,
  ThemeLast = ThemeBlue,
};

class DLLEXPORT Control : public Windows::Window
{
private:
  COLORREF      backColor;
  Gdip::Bitmap* buffer;
  HWND          mNotifyWindow;

protected:
  virtual VOID  onEraseBackground(Event::EraseBackgroundEvent&);
  virtual VOID  onPaint();
  virtual VOID  onSize(Event::SizeEvent&);

  virtual VOID  onControlPaint(ControlPaintEvent& iEvent) = 0;

  VOID          sendNotify(NMHDR& iValue);

public:
  SPLINL COLORREF getBackColor()
  {
    return backColor;
  }
  SPLINL VOID   setBackColor(COLORREF value)
  {
    backColor = value;
  }

  SPLINL HWND   getNotifyWindow()
  {
    return mNotifyWindow;
  }
  SPLINL VOID   setNotifyWindow(HWND value)
  {
    mNotifyWindow = value;
  }

  static VOID   setTheme(const ControlTheme* value);
  static VOID   setTheme(ThemeStyle value);
  static const ControlTheme& getTheme();

  SPLINL Control()
  {
    backColor     = 0xFFFFFFFF;
    buffer        = NULL;
    mNotifyWindow = NULL;
  }

  SPLINL virtual ~Control()
  {
    delete buffer;
  }
};

#endif